home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_amanda.idb / usr / freeware / bin / amverify.z / amverify
Encoding:
Text File  |  1999-07-16  |  9.3 KB  |  374 lines

  1. #!/bin/sh
  2. #
  3. # (C) 1996 by ICEM Systems GmbH
  4. # Author: Axel Zinser (fifi@icem.de)
  5. #
  6. # amverify: check amanda tapes and report errors
  7.  
  8. prefix=/usr/freeware
  9. exec_prefix=${prefix}
  10. sbindir=/usr/freeware/bin
  11. libexecdir=/usr/freeware/libexec
  12.  
  13. PATH=$libexecdir:$sbindir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
  14. export PATH
  15.  
  16. USE_VERSION_SUFFIXES="no"
  17. if [ "$USE_VERSION_SUFFIXES" = "yes" ]; then
  18.     SUF="-2.4.1p1"
  19. else
  20.     SUF=
  21. fi
  22.  
  23. report() {
  24.     $ECHO "$@" >&2
  25.     $ECHO "$@" >> $REPORT
  26. }
  27.  
  28. getparm() {
  29.     (cd $CONFIG_DIR/$CONFIG; $AMGETCONF $1 2>/dev/null) | grep -v BUGGY
  30. }
  31.  
  32. sendreport() {
  33.     TAPES=`cat $TAPELIST`
  34.     if [ -f $REPORT -a X"$REPORTTO" != X"" ]; then
  35.         (
  36.         $ECHO "Tapes: $TAPES"
  37.         if [ -s $DEFECTS ]; then
  38.             $ECHO "Errors found: "
  39.             cat $DEFECTS
  40.         else
  41.             $ECHO "No errors found!"
  42.         fi
  43.         $ECHO
  44.  
  45.         [ -s $REPORT ] \
  46.             && cat $REPORT
  47.         ) | $MAIL -s "$ORG AMANDA VERIFY REPORT FOR $TAPES" $REPORTTO
  48.     fi
  49. }
  50.  
  51. ###
  52. # This function is called to process one dump image.  Standard input is
  53. # the dump image.  We parse the header and decide if it is a GNU tar
  54. # dump or a system dump.  Then we do a catalog operation to /dev/null
  55. # and finally a "cat" to /dev/null to soak up whatever data is still in
  56. # the pipeline.
  57. #
  58. # In the case of a system restore catalogue, this does not fully check
  59. # the integrity of the dump image because system restore programs stop
  60. # as soon as they are done with the directories, which are all at the
  61. # beginning.  But the trailing cat will at least make sure the whole
  62. # image is readable.
  63. ###
  64.  
  65. doonefile() {
  66.  
  67.     ###
  68.     # The goal here is to collect the first 32 KBytes and save the
  69.     # first line.  But the pipe size coming in to us from amrestore
  70.     # is highly system dependent and "dd" does not do reblocking.
  71.     # So we pick a block size that is likely to always be available in
  72.     # the pipe and a count to take it up to 32 KBytes.  Worst case,
  73.     # this could be changed to "bs=1 count=32k".  We also have to
  74.     # soak up the rest of the output after the "head" so an EPIPE
  75.     # does not go back and terminate the "dd" early.
  76.     ###
  77.  
  78.     HEADER=`$DD bs=512 count=64 | ( head -1 ; cat > /dev/null )`
  79.     CMD=
  80.     result=1
  81.     if [ X"$HEADER" = X"" ]; then
  82.         $ECHO "** No header" > $TEMP/errors
  83.     else
  84.         set X $HEADER
  85.         shift
  86.         shift 9
  87.         if [ X"$1" = X"program" -a X"$2" != X"" ]; then
  88.             if [ X"$TAR" != X"" -a X"$2" = X"$TAR" ]; then
  89.                 CMD=$TAR
  90.                 ARGS="tf -"
  91.             elif [ X"$DUMP" != X"" -a X"$2" = X"$DUMP" ]; then
  92.                 CMD=$RESTORE
  93.                 if [ $IS_AIX -eq 1 ]; then
  94.                     ARGS=-tB
  95.                 else
  96.                     ARGS="tbf 2 -"
  97.                 fi
  98.             else
  99.                 $ECHO "** Cannot do $2 dumps" > $TEMP/errors
  100.                 result=999    # flag as not really an error
  101.             fi
  102.         else
  103.             $ECHO "** Cannot find dump type" > $TEMP/errors
  104.         fi
  105.     fi
  106.     if [ X"$CMD" != X"" ]; then
  107.         $CMD $ARGS > /dev/null 2> $TEMP/errors
  108.         result=$?
  109.     fi
  110.     cat >/dev/null
  111.     $ECHO $result
  112. }
  113.  
  114. #
  115. # some paths
  116. #
  117. #    CONFIG_DIR    directory in which the config file resides
  118. #    AMRESTORE    full path name of amrestore
  119. #    AMGETCONF    full path name of getconf
  120. #    TAR        ditto for GNU-tar
  121. #    DUMP        ditto for the system dump program
  122. #    RESTORE        ditto for the system restore program
  123. #    MT        ditto for mt
  124. #    DD        ditto for dd
  125. #    MAIL        mail program
  126. #    ECHO        echo
  127. #    ECHOARG        echo argument to supress line feed
  128. #    ECHOSUF        echo meta character to supress line feed
  129. #    MTOPT        flag given to MT to specify tape device: -f or -t
  130. #    IS_AIX        true if this is an AIX system
  131.  
  132. CONFIG_DIR=/usr/freeware/etc/amanda
  133. libexecdir=$libexecdir
  134. sbindir=$sbindir
  135. AMRESTORE=$sbindir/amrestore$SUF
  136. AMGETCONF=$libexecdir/getconf$SUF
  137. AMTAPE=$sbindir/amtape$SUF
  138. TAR=/usr/freeware/bin/tar
  139. DUMP=/sbin/dump
  140. RESTORE=/sbin/restore
  141. MT=/sbin/mt
  142. MAIL=/usr/sbin/Mail
  143. DD=/sbin/dd
  144. ECHO=/bin/echo
  145. ECHOARG=""
  146. ECHOSUF="\c"
  147. MTOPT=-f
  148. if [ `/bin/uname -s 2>/dev/null` = AIX ]; then
  149.     IS_AIX=1
  150. else
  151.     IS_AIX=0
  152. fi
  153.  
  154. #
  155. # config file
  156. #
  157. SLOT=0
  158. CONFIG=$1
  159. [ X"$CONFIG" = X"" ] \
  160.     && $ECHO "usage: amverify$SUF <config>" >&2 \
  161.     && exit 1
  162.  
  163. AMCONFIG=$CONFIG_DIR/$CONFIG/amanda.conf
  164. [ ! -f $AMCONFIG ] \
  165.     && $ECHO "Cannot find config file $AMCONFIG" >&2 \
  166.     && exit 1
  167.  
  168. cd $CONFIG_DIR/$CONFIG
  169.  
  170. TPCHANGER=`getparm tpchanger`
  171. if [ X"$TPCHANGER" = X"" ]; then
  172.     $ECHO "No tape changer..."
  173.     DEVICE=`getparm tapedev`
  174.     [ X"$DEVICE" = X"" ] \
  175.         && $ECHO "No tape device..." >&2 \
  176.         && exit 1
  177.     [ ! -c $DEVICE ] \
  178.         && $ECHO "Not a character special device: $DEVICE" >&2 \
  179.         && exit 1
  180.     $ECHO "Tape device is $DEVICE..."
  181.     SLOTS=1
  182. else
  183.     CHANGER_SLOT=${2:-current}
  184.     $ECHO "Tape changer is $TPCHANGER..."
  185.     SLOTS=`getparm runtapes`
  186.     [ X"$SLOTS" = X"" ] && SLOTS=1
  187.     if [ $SLOTS -eq 1 ]; then
  188.         p=""
  189.     else
  190.         p=s
  191.     fi
  192.     $ECHO "$SLOTS slot${p}..."
  193.     MAXRETRIES=2
  194. fi
  195.  
  196. #
  197. # check the accessability
  198. #
  199. [ X"$TAR" != X"" -a ! -x "$TAR" ] \
  200.     && $ECHO "GNU tar not found: $TAR" >&2
  201. [ X"$DUMP" != X"" -a \( X"$RESTORE" = X"" -o ! -x "$RESTORE" \) ] \
  202.     && $ECHO "System restore program not found: $RESTORE" >&2
  203. [ ! -x $AMRESTORE ] \
  204.     && $ECHO "amrestore not found: $AMRESTORE" >&2 \
  205.     && exit 1
  206.  
  207. REPORTTO=`getparm mailto`
  208. if [ X"$REPORTTO" = X"" ]; then
  209.     $ECHO "No notification by mail!"
  210. else
  211.     $ECHO "Verify summary to $REPORTTO"
  212. fi
  213.  
  214. ORG=`getparm org`
  215. if [ X"$ORG" = X"" ]; then
  216.     $ECHO "No org in amanda.conf -- using $CONFIG"
  217.     ORG=$CONFIG
  218. fi
  219.  
  220. #
  221. # ok, let's do it
  222. #
  223. #    TEMP        directory for temporary tar archives and stderr
  224. #    DEFECTS        defect list
  225. #    REPORT        report for mail
  226.  
  227. TEMP=/tmp/amverify.$$
  228. trap 'rm -fr $TEMP' 0
  229. if ( umask 077 ; mkdir $TEMP ) ; then
  230.     :
  231. else
  232.     $ECHO "Cannot create $TEMP" >&2
  233.     exit 1
  234. fi
  235. DEFECTS=$TEMP/defects; rm -f $DEFECTS
  236. REPORT=$TEMP/report; rm -f $REPORT
  237. TAPELIST=$TEMP/tapelist; rm -f $TAPELIST
  238. EXITSTAT=$TEMP/amrecover.exit; rm -rf $EXITSTAT
  239.  
  240. trap 'report "aborted!"; $ECHO "aborted!" >> $DEFECTS; sendreport; rm -fr $TEMP; exit 1' 1 2 3 4 5 6 7 8 10 12 13 14 15
  241.  
  242. $ECHO "Defects file is $DEFECTS" >&2
  243. report "amverify $CONFIG"
  244. report "`date`"
  245. report ""
  246.  
  247. # ----------------------------------------------------------------------------
  248.  
  249. while [ $SLOT -lt $SLOTS ]; do
  250.     SLOT=`expr $SLOT + 1`
  251.     #
  252.     # Tape Changer: dial slot
  253.     #
  254.     if [ X"$TPCHANGER" != X"" ]; then
  255.         report "Loading ${CHANGER_SLOT} slot..."
  256.         $AMTAPE $CONFIG slot $CHANGER_SLOT > $TEMP/amtape.out 2>&1
  257.         THIS_SLOT=$CHANGER_SLOT
  258.         CHANGER_SLOT=next
  259.         RESULT=`grep "changed to slot" $TEMP/amtape.out`
  260.         [ X"$RESULT" = X"" ] \
  261.             && report "** Error loading slot $THIS_SLOT" \
  262.             && report "`cat $TEMP/amtape.out`" \
  263.             && cat $TEMP/amtape.out >> $DEFECTS \
  264.             && continue
  265.         DEVICE=`$AMTAPE $CONFIG device`
  266.     fi
  267.     report "Using device $DEVICE"
  268.     if [ $IS_AIX -eq 0 ]; then
  269.  
  270.         # The AIX "mt stat" function does not really do anything
  271.         # w.r.t. checking the drive for ready, and in fact, will
  272.         # fail under some conditions (e.g. if the tape "file"
  273.         # is a symlink to the real device).  We let the rewind
  274.         # right after this take care of the cases "mt stat"
  275.         # does not catch.
  276.  
  277.         $ECHO $ECHOARG "Waiting for device to go ready...\r$ECHOSUF" >&2
  278.         until $MT $MTOPT $DEVICE stat >/dev/null 2>&1; do
  279.             sleep 3
  280.         done
  281.     fi
  282.     $ECHO $ECHOARG "Rewinding...                             \r$ECHOSUF" >&2
  283.     until $MT $MTOPT $DEVICE rewind; do
  284.         sleep 3
  285.     done
  286.     $ECHO $ECHOARG "Processing label...\r$ECHOSUF" >&2
  287.     $DD if=$DEVICE count=1 bs=32k 2> $TEMP/errors > $TEMP/header
  288.     [ ! -s $TEMP/header ] \
  289.         && report "** Error reading label on tape" \
  290.         && cat $TEMP/errors >> $DEFECTS \
  291.         && continue
  292.     TAPENDATE=`grep AMANDA: $TEMP/header | sed 's/^AMANDA: TAPESTART //'`
  293.     [ X"$TAPENDATE" = X"" ] \
  294.         && report "** No amanda tape in slot" \
  295.         && continue
  296.     set X $TAPENDATE
  297.     shift
  298.     VOLUME=$4
  299.     DWRITTEN=$2
  300.     report "Volume $VOLUME, Date $DWRITTEN"
  301.     [ X"$DWRITTEN" = X"0" -o X"$DWRITTEN" = X"X" ] \
  302.         && report "Fresh tape. Skipping..." \
  303.         && continue
  304.     $ECHO $ECHOARG "$VOLUME $ECHOSUF" >> $TAPELIST
  305.     $ECHO $ECHOARG "Rewinding...\r$ECHOSUF" >&2
  306.     until $MT $MTOPT $DEVICE rewind; do
  307.         sleep 3
  308.     done
  309.     ERG=0
  310.     ERRORS=0
  311.     while [ $ERG = 0 ]; do
  312.         $ECHO $ECHOARG "Reading...\r$ECHOSUF" >&2
  313.         RESULT=`$AMRESTORE -h -p $DEVICE 2> $TEMP/amrestore.out \
  314.             | doonefile 2> $TEMP/onefile.errors`
  315.         FILE=`grep restoring $TEMP/amrestore.out | sed 's/^.*restoring //'`
  316.         EOF=`grep "reached end of tape" $TEMP/amrestore.out`
  317.         # amrestore:   0: restoring sundae._mnt_sol1_usr.19961127.1
  318.         if [ X"$FILE" != X"" -a X"$RESULT" = X"0" ]; then
  319.             report "Checked $FILE"
  320.         elif [ X"$FILE" != X"" -a X"$RESULT" = X"999" ]; then
  321.             report "Skipped $FILE (`cat $TEMP/errors`)"
  322.         elif [ -n "$EOF" ]; then
  323.             report "End-of-Tape detected."
  324.             break
  325.         else
  326.             report "** Error detected ($FILE)"
  327.             $ECHO "$VOLUME ($FILE):" >>$DEFECTS
  328.             [ -s $TEMP/amrestore.out ] \
  329.                 && report "`cat $TEMP/amrestore.out`" \
  330.                 && cat $TEMP/amrestore.out >>$DEFECTS
  331.             [ -s $TEMP/errors ] \
  332.                 && report "`cat $TEMP/errors`" \
  333.                 && cat $TEMP/errors >>$DEFECTS
  334.             [ -s $TEMP/onefile.errors ] \
  335.                 && report "`cat $TEMP/onefile.errors`" \
  336.                 && cat $TEMP/onefile.errors >>$DEFECTS
  337.             ERRORS=`expr $ERRORS + 1`
  338.             [ $ERRORS -gt 5 ] \
  339.                 && report "Too many errors." \
  340.                 && break
  341.         fi
  342.     done
  343.     $ECHO $ECHOARG "Rewinding...\r$ECHOSUF" >&2
  344.     until $MT $MTOPT $DEVICE rewind; do
  345.         sleep 3
  346.     done
  347.     $ECHO
  348.     rm -f $TEMP/header \
  349.           $TEMP/amtape.out \
  350.           $TEMP/amrestore.out \
  351.           $TEMP/errors \
  352.           $TEMP/onefile.errors
  353. done
  354.  
  355. if [ X"$TPCHANGER" != X"" ]; then
  356.     report "Advancing past the last tape..."
  357.     $AMTAPE $CONFIG slot advance 2> $TEMP/amtape.out
  358.     RESULT=`grep "changed to slot" $TEMP/amtape.out`
  359.     [ X"$RESULT" = X"" ] \
  360.         && report "** Error advancing after last slot" \
  361.         && report "`cat $TEMP/amtape.out`" \
  362.         && cat $TEMP/amtape.out >> $DEFECTS
  363. fi
  364.  
  365. $ECHO >> $TAPELIST
  366.  
  367. [ -s $DEFECTS ] \
  368.     && $ECHO "Errors found: " \
  369.     && cat $DEFECTS
  370.  
  371. sendreport
  372.  
  373. exit 0
  374.